1、并发和竞争
	在以下情况会存在并发：
		1）进程之间，一个进程被另一个进程打断，或进程时间片结束
		2）进程和中断之间，进程可能被中断打断
		2）多个CPU之间，多个CPU之间会同时执行多个进程
	在并发状态对共享资源进行访问将出现竞争。
2、中断屏蔽
	中断屏蔽可以用来解决进程和中断之间的竞争(此方法只适用于单核，在多核情况还需配合自旋锁)，在内核中可以通过
local_irq_save关闭本核中断，通过local_irq_restore恢复本核中断。
3、原子变量
	原子变量的操作是不可分割的，不需要考虑并发问题，对原子变量的操作需要采用内核提供的API来完成。
	原子变量API：
		//静态初始化原子变量
		ATOMIC_INIT(int i)	
		//读取 v 的值，并且返回
		int atomic_read(atomic_t *v) 
		//向 v 写入 i 值
		void atomic_set(atomic_t *v, int i)
		//给 v 加上 i 值
		void atomic_add(int i, atomic_t *v)
		//从 v 减去 i 值
		void atomic_sub(int i, atomic_t *v)
		//给 v 加 1，也就是自增
		void atomic_inc(atomic_t *v)
		//从 v 减 1，也就是自减
		void atomic_dec(atomic_t *v)
		//从 v 减 1，并且返回 v 的值
		int atomic_dec_return(atomic_t *v)
		//给 v 加 1，并且返回 v 的值
		int atomic_inc_return(atomic_t *v)
		//从 v 减 i，如果结果为 0 就返回真，否则返回假
		int atomic_sub_and_test(int i, atomic_t *v)
		//从 v 减 1，如果结果为 0 就返回真，否则返回假
		int atomic_dec_and_test(atomic_t *v)
		//给 v 加 1，如果结果为 0 就返回真，否则返回假
		int atomic_inc_and_test(atomic_t *v)
		//给 v 加 i，如果结果为负就返回真，否则返回假
		int atomic_add_negative(int i, atomic_t *v)
4、自旋锁
	自旋锁可以用于解决进程与进程（包括运行在不同核心的进程）之间的竞争问题，配合中断屏蔽可以解决SMP系统中进程
与中断之间的竞争问题。
	自旋锁API：
		//定义并初始化一个自选变量。
		DEFINE_SPINLOCK(spinlock_t lock)
		//初始化自旋锁
		void spin_lock_init(spinlock_t *lock)
		//获取指定的自旋锁，也叫做加锁。
		void spin_lock(spinlock_t *lock)
		//释放指定的自旋锁。
		void spin_unlock(spinlock_t *lock)
		//尝试获取指定的自旋锁，如果没有获取到就返回 0
		int spin_trylock(spinlock_t *lock)
		//检查指定的自旋锁是否被获取，如果没有被获取就返回非 0，否则返回 0
		int spin_is_locked(spinlock_t *lock)
		//保存中断状态，并获取自旋锁
		void spin_lock_irqsave(spinlock_t *lock, unsigned long flags)
		//恢复中断状态，并释放自旋锁
		void spin_unlock_irqrestore(spinlock_t *lock, unsigned long flags)
	自旋锁特性：
		1）获取自旋锁不会引起进程休眠，所以自旋锁可以在中断中使用、加锁的时间要尽可能的短、加锁时不要执行可能
	会引起进程休眠的函数。
		2）自旋锁不可递归使用
		3）被自旋锁保护的资源需要在中断中使用时，在进程中应采用spin_lock_irqsave和spin_unlock_irqrestore来进
	行加锁和解锁
		4）自旋锁加锁和解锁必须成对使用
5、信号量
	信号量可以用于解决进程与进程（包括运行在不同核心的进程）之间的竞争问题，也可以用于进程之间、进程与中断之
间的同步。
	信号量API：
		//定义一个信号量，并且设置信号量的值为 1
		DEFINE_SEMAPHORE(name)
		//初始化信号量 sem，设置信号量值为 val。
		void sema_init(struct semaphore *sem, int val)
		//获取信号量
		void down(struct semaphore *sem)
		//尝试获取信号量，不会进入休眠，可以在中断中使用
		int down_trylock(struct semaphore *sem);
		//获取信号量，但是休眠后能被信号唤醒
		int down_interruptible(struct semaphore *sem)
		//释放信号量
		void up(struct semaphore *sem)
	信号量的特性：
		1）获取信号量时如果信号量不可用则会进行休眠
		2）不可再中断中等待信号量，但是可以采用down_trylock尝试获取信号量
		3）可以在中断中释放信号量
		4）用于互斥时获取和释放必须成对使用
6、互斥体
	互斥体可以用于解决进程与进程（包括运行在不同核心的进程）之间的竞争问题。
	互斥体API：
		//定义并初始化一个互斥体
		DEFINE_MUTEX(name)
		//初始化互斥体
		void mutex_init(mutex *lock)
		//获取互斥体
		void mutex_lock(struct mutex *lock)
		//释放互斥体
		void mutex_unlock(struct mutex *lock)
		//尝试获取互斥体
		int mutex_trylock(struct mutex *lock)
		//互斥体是否被获取，如果是的话就返回 1，否则返回 0
		int mutex_is_locked(struct mutex *lock)
		//获取互斥体，但是休眠后能被信号唤醒
		int mutex_lock_interruptible(struct mutex *lock)
	互斥体的特性：
		1）不可再中断中使用，包括mutex_trylock
		2）不可递归使用
		3）获取和释放必须成对使用
		4）消耗的资源比信号量小
